package com.wanmait.schedule.controller;


import com.wanmait.schedule.entity.*;
import com.wanmait.schedule.service.*;
import com.wanmait.schedule.util.AjaxResult;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;

@RestController
@RequestMapping("/manage/auto")
public class AutoController {

    @Resource
    private CoursePlanService coursePlanService;
    @Resource
    private ScheduleService scheduleService;
    @Resource
    private ClassesService classesService;
    @Resource
    private TeacherService teacherService;
    @Resource
    private ClassroomService classroomService;
    @Resource
    private CourseService courseService;

    @PostMapping("autolist")
    public AjaxResult autolist(@DateTimeFormat(pattern = "yyyy-MM-dd") Date date){
        Date date1 = date;
        Date date2 = new Date(date.getTime()+7*24*60*60*1000);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        //这周是否有课
        List<Schedule> sch = scheduleService.find(dateFormat.format(date),dateFormat.format(date2));
        //这周是否已发布
        List<Schedule> sc = scheduleService.checkPublish(dateFormat.format(date),dateFormat.format(date2));
        System.out.println(sch.size());
        System.out.println(sc.size());
        //有课 并且 已发布 不能自动排
        //sch.size=0表示没课 !=0表示有课   sc.size=0表示没有未发布的 都发布了 !=0表示没发布
        if(sch.size()!=0 && sc.size()==0){
            return AjaxResult.error(20002,"课表已发布，不能再使用自动排课，如需修改，请手动修改");
        }
        //获得课程计划
        List<CoursePlan> coursePlanList = coursePlanService.list();
        //获得所有课程的总节数
        List<Course> courses = courseService.list();
        Map<Integer, Integer> courseMap = new HashMap<>();
        for (Course c:courses){
            courseMap.put(c.getId(), c.getCount());
        }
        //用来放置 一周所有的课程
        List<Schedule> scheduleList = new ArrayList<>();
        Map<Integer,Integer> courseNumber = new HashMap<>();
        Integer f=0;
        for(CoursePlan c : coursePlanList){
            //获取上一节课上到第几节
            int number = scheduleService.findNum(c.getCourseId(),c.getClassId(),date);
            f++;
            courseNumber.put(f,number+1);
            for(int p=0;p<c.getWeekCount() ;p++){
                Schedule s = new Schedule();
                s.setTeacherId(c.getTeacherId());
                s.setCourseId(c.getCourseId());
                s.setClassesId(c.getClassId());
                //s.setNumber(number+1+p);
                s.setId(f);
                //courseMap.put(c.getCourseId(),courseMap.get(c.getCourseId()));
                scheduleList.add(s);
                //如果课程总节数=课程节数+1  说明是最后一节课 删除计划 跳出循环
                if (courseMap.get(c.getCourseId()) == number+p+1){
                    //删除计划
                    coursePlanService.removeById(c.getId());
                    break;
                }
            }
        }
        //打乱所有课程
        Collections.shuffle(scheduleList);
        //放入number
        for(Schedule s : scheduleList){
            s.setNumber(courseNumber.get(s.getId()));
            courseNumber.put(s.getId(),courseNumber.get(s.getId())+1);
        }

        //获得所有的教室
        List<Classroom> classroomList = classroomService.listStudy();
        int schedule[][] = new int[7][classroomList.size()];
        //schedule = auto(schedule,scheduleList,classroomList,0,0,0);
        schedule = auto(scheduleList,classroomList);
        int flag=0;
        for(int i=0;i<7;i++) {
            //求这一周七天的的时间
            Instant instant = date.toInstant();
            ZoneId zoneId = ZoneId.systemDefault();
            LocalDateTime localDateTime;
            for (int j=0;j<classroomList.size();j++) {
                if(schedule[i][j] != -1){
                    localDateTime = instant.atZone(zoneId).toLocalDateTime();
                    scheduleList.get(schedule[i][j]).setCourseTime(localDateTime).setClassroomId(classroomList.get(j).getId()).setInputId(1);
                    scheduleList.get(schedule[i][j]).setId(null);
                    flag++;
                }
            }
            date = new Date(date.getTime()+24*60*60*1000);
        }
//        System.out.println(flag);
//        System.out.println(scheduleList.size());
        if(flag == scheduleList.size()){
            //如果排课成功，首先删除这一周全部的课
            scheduleService.delete(dateFormat.format(date1),dateFormat.format(date2));
            //再将排好的课加入数据库
            for(Schedule s:scheduleList){
                scheduleService.save(s);
            }
            return AjaxResult.success("排课成功");
        }
        else {
            return AjaxResult.error("20001","排课失败");
        }
    }
    private int[][] auto(List<Schedule> scheduleList,List<Classroom> classroomList){
        int schedule[][] = new int[7][classroomList.size()];
        for(int j=0;j<7;j++) {
            for (int g = 0; g < classroomList.size(); g++) {
                schedule[j][g]=-1;
            }
        }
        Boolean flagRoom = true;
        //获得每个班级的人数
        List<Classes> classes = classesService.list();
        Map<Integer, Integer> classMap = new HashMap<>();
        for (Classes c:classes){
            classMap.put(c.getId(), c.getStudentCount());
        }
        for(int i=0;i<scheduleList.size();i++){
            top:
            for(int j=0;j<7;j++){
                for(int g=0;g<classroomList.size();g++){
                    //判断这个教室容量是否够使用 以及 这个教室这一天是否已经安排了课
                    if(schedule[j][g] == -1 && classroomList.get(g).getCapacity()>=classMap.get(scheduleList.get(i).getClassesId())){    //  +容量
                        //判断一列 这一天的所有教室有没有这个班的课   这一天所有安排好的课没有这个教师
                        for(int num=0;num<classroomList.size();num++){
                            if(schedule[j][num] != -1){
                                if(scheduleList.get(schedule[j][num]).getClassesId() == scheduleList.get(i).getClassesId() ||
                                        scheduleList.get(schedule[j][num]).getTeacherId() == scheduleList.get(i).getTeacherId()){
                                    flagRoom = false;
                                    break;
                                }
                            }
                        }
                        if(flagRoom){
                            schedule[j][g] = i;
                            break top;
                        }
                        flagRoom = true;
                    }
                }
            }
        }
        return schedule;
    }

    /*private int[][] auto(int schedule[][],List<Schedule> scheduleList,List<Classroom> classroomList,int schedulenum,int daynum,int roomnum){
        Boolean flagDay = true;
        Boolean flagRoom = true;
        for(int i=schedulenum;i<scheduleList.size();i++){
            for(int j=daynum;j<7;j++){
                for(int g=roomnum;g<classroomList.size();g++){
                    //判断一行七天 有没有用这个教室
                    for(int num1=0;num1<7;num1++){
                        if(scheduleList.get(schedule[num1][g]).getClassroomId() == scheduleList.get(i).getClassroomId()){
                            flagDay = false;
                            break;
                        }
                    }
                    //判断一列 这一天的所有教室有没有这个班的课
                    for(int num2=0;num2<classroomList.size();num2++){
                        if(scheduleList.get(schedule[j][num2]).getClassesId() == scheduleList.get(i).getClassesId()){
                            flagRoom = false;
                            break;
                        }
                    }
                    if(flagDay && flagRoom){
                        schedule[j][g] = i;
                        number++;
                        if (number==scheduleList.size()){
                            return schedule;
                        }
                    }
                    else {
                        schedule = auto(schedule,scheduleList,classroomList,i,j,g);
                    }
                    flagDay = true;
                    flagRoom = true;
                }
            }
        }
        return schedule;
    }*/
}
